#ifndef _WX_LISTH__
#define _WX_LISTH__

#include "wx/defs.h"
#include "wx/object.h"
#include "wx/string.h"

extern "C"
{
  typedef int ( * LINKAGEMODE wxSortCompareFunction )( const void *elem1, const void *elem2 );
}

class wxObjectListNode;
typedef wxObjectListNode wxNode;
typedef int ( * LINKAGEMODE wxListIterateFunction )( void *current );

#if !defined(wxENUM_KEY_TYPE_DEFINED)
#define wxENUM_KEY_TYPE_DEFINED

enum wxKeyType {
  wxKEY_NONE,
  wxKEY_INTEGER,
  wxKEY_STRING
};

#endif

#define wxLIST_COMPATIBILITY

union wxListKeyValue {
  long integer;
  wxChar *string;
};

class wxListKey {
  public:
    wxListKey() : m_keyType( wxKEY_NONE ) { }
    wxListKey( long i ) : m_keyType( wxKEY_INTEGER ) { m_key.integer = i; }
    wxListKey( const wxChar *s ) : m_keyType( wxKEY_STRING ) { m_key.string = wxStrdup( s ); }
    wxListKey( const wxString& s ) : m_keyType( wxKEY_STRING ) { m_key.string = wxStrdup( s.c_str() ); }
    wxKeyType GetKeyType() const { return m_keyType; }
    const wxChar *GetString() const
    { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; }
    long GetNumber() const
    { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
    bool operator==( wxListKeyValue value ) const ;
    ~wxListKey() {
      if( m_keyType == wxKEY_STRING ) {
        free( m_key.string );
      }
    }

  private:
    wxKeyType m_keyType;
    wxListKeyValue m_key;
};

extern wxListKey wxDefaultListKey;
class wxListBase;
class wxNodeBase {
    friend class wxListBase;
  public:
    wxNodeBase( wxListBase *list = ( wxListBase * )NULL,
                wxNodeBase *previous = ( wxNodeBase * )NULL,
                wxNodeBase *next = ( wxNodeBase * )NULL,
                void *data = NULL,
                const wxListKey& key = wxDefaultListKey );

    virtual ~wxNodeBase();
    const wxChar *GetKeyString() const { return m_key.string; }
    long GetKeyInteger() const { return m_key.integer; }
    void SetKeyString( wxChar* s ) { m_key.string = s; }
    void SetKeyInteger( long i ) { m_key.integer = i; }

    #ifdef wxLIST_COMPATIBILITY
    wxDEPRECATED( wxNode *Next() const );
    wxDEPRECATED( wxNode *Previous() const );
    wxDEPRECATED( wxObject *Data() const );
    #endif // wxLIST_COMPATIBILITY

  protected:
    wxNodeBase *GetNext() const { return m_next; }
    wxNodeBase *GetPrevious() const { return m_previous; }
    void *GetData() const { return m_data; }
    void SetData( void *data ) { m_data = data; }
    int IndexOf() const;
    virtual void DeleteData() { }
  public:
    void** GetDataPtr() const { return &( ( ( wxNodeBase* )this )->m_data ); }
  private:
    wxListKeyValue m_key;
    void        *m_data;        // user data
    wxNodeBase  *m_next,        // next and previous nodes in the list
                *m_previous;

    wxListBase  *m_list;        // list we belong to

    DECLARE_NO_COPY_CLASS( wxNodeBase )
};

class wxList;

class wxListBase : public wxObject {
    friend class wxNodeBase; // should be able to call DetachNode()
    friend class wxHashTableBase;   // should be able to call untyped Find()

  public:
    // default ctor & dtor
    wxListBase( wxKeyType keyType = wxKEY_NONE ) { Init( keyType ); }
    virtual ~wxListBase();
    size_t GetCount() const { return m_count; }
    bool IsEmpty() const { return m_count == 0; }
    void Clear();
    void DeleteContents( bool destroy ) { m_destroy = destroy; }
    bool GetDeleteContents() const
    { return m_destroy; }
    wxKeyType GetKeyType() const
    { return m_keyType; }
    void SetKeyType( wxKeyType keyType ) { wxASSERT( m_count == 0 ); m_keyType = keyType; }

    #ifdef wxLIST_COMPATIBILITY
    wxDEPRECATED( int Number() const );             // use GetCount instead.
    wxDEPRECATED( wxNode *First() const );          // use GetFirst
    wxDEPRECATED( wxNode *Last() const );           // use GetLast
    wxDEPRECATED( wxNode *Nth( size_t n ) const );  // use Item
    wxDEPRECATED( operator wxList & () const );
    #endif // wxLIST_COMPATIBILITY

  protected:
    virtual wxNodeBase *CreateNode( wxNodeBase *prev, wxNodeBase *next,
                                    void *data,
                                    const wxListKey& key = wxDefaultListKey ) = 0;

    #ifdef __SALFORDC__
  public:
    #endif

    wxListBase( size_t count, void *elements[] );
    wxListBase( void *object, ... );

  protected:
    void Assign( const wxListBase& list ) { Clear(); DoCopy( list ); }
    wxNodeBase *GetFirst() const { return m_nodeFirst; }
    wxNodeBase *GetLast() const { return m_nodeLast; }
    wxNodeBase *Item( size_t index ) const;
    void *operator[]( size_t n ) const {
      wxNodeBase *node = Item( n );
      return node ? node->GetData() : ( wxNodeBase * )NULL;
    }
    wxNodeBase *Prepend( void *object ) { return ( wxNodeBase * )wxListBase::Insert( object ); }
    wxNodeBase *Append( void *object );
    wxNodeBase *Insert( void *object ) { return Insert( ( wxNodeBase* )NULL, object ); }
    wxNodeBase *Insert( size_t pos, void *object ) {
      return pos == GetCount() ? Append( object )
             : Insert( Item( pos ), object );
    }
    wxNodeBase *Insert( wxNodeBase *prev, void *object );

    // keyed append
    wxNodeBase *Append( long key, void *object );
    wxNodeBase *Append( const wxChar *key, void *object );
    wxNodeBase *DetachNode( wxNodeBase *node );
    bool DeleteNode( wxNodeBase *node );
    bool DeleteObject( void *object );
    wxNodeBase *Find( const void *object ) const;
    wxNodeBase *Find( const wxListKey& key ) const;
    int IndexOf( void *object ) const;
    void Sort( const wxSortCompareFunction compfunc );
    void *FirstThat( wxListIterateFunction func );
    void ForEach( wxListIterateFunction func );
    void *LastThat( wxListIterateFunction func );
    void Reverse();
    void DeleteNodes( wxNodeBase* first, wxNodeBase* last );
  private:
    void Init( wxKeyType keyType = wxKEY_NONE );
    void DoCopy( const wxListBase& list );
    wxNodeBase *AppendCommon( wxNodeBase *node );
    void DoDeleteNode( wxNodeBase *node );

    size_t m_count;             // number of elements in the list
    bool m_destroy;             // destroy user data when deleting list items?
    wxNodeBase *m_nodeFirst,    // pointers to the head and tail of the list
               *m_nodeLast;

    wxKeyType m_keyType;        // type of our keys (may be wxKEY_NONE)
};

#define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, ptrop)        \
  typedef int (*wxSortFuncFor_##name)(const T **, const T **);            \
  \
  class nodetype : public wxNodeBase                                   \
  {                                                                       \
  public:                                                                 \
    nodetype(wxListBase *list = (wxListBase *)NULL,                     \
             nodetype *previous = (nodetype *)NULL,                     \
             nodetype *next = (nodetype *)NULL,                         \
             T *data = (T *)NULL,                                       \
             const wxListKey& key = wxDefaultListKey)                   \
      : wxNodeBase(list, previous, next, data, key) { }               \
    \
    nodetype *GetNext() const                                           \
    { return (nodetype *)wxNodeBase::GetNext(); }                   \
    nodetype *GetPrevious() const                                       \
    { return (nodetype *)wxNodeBase::GetPrevious(); }               \
    \
    T *GetData() const                                                  \
    { return (T *)wxNodeBase::GetData(); }                          \
    void SetData(T *data)                                               \
    { wxNodeBase::SetData(data); }                                  \
    \
  protected:                                                              \
    virtual void DeleteData();                                          \
    \
    DECLARE_NO_COPY_CLASS(nodetype)                                     \
  };                                                                      \
  \
  class name : public wxListBase                                       \
  {                                                                       \
  public:                                                                 \
    typedef nodetype Node;                                              \
    class compatibility_iterator                                     \
    {                                                                   \
    public:                                                             \
      compatibility_iterator(Node *ptr = NULL) : m_ptr(ptr) { }       \
      \
      Node *operator->() const { return m_ptr; }                      \
      operator Node *() const { return m_ptr; }                       \
      \
    private:                                                            \
      Node *m_ptr;                                                    \
    };                                                                  \
    \
    name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType)          \
    { }                                                             \
    name(const name& list) : wxListBase(list.GetKeyType())              \
    { Assign(list); }                                               \
    name(size_t count, T *elements[])                                   \
      : wxListBase(count, (void **)elements) { }                      \
    \
    name& operator=(const name& list)                                   \
    { Assign(list); return *this; }                                 \
    \
    nodetype *GetFirst() const                                          \
    { return (nodetype *)wxListBase::GetFirst(); }                  \
    nodetype *GetLast() const                                           \
    { return (nodetype *)wxListBase::GetLast(); }                   \
    \
    nodetype *Item(size_t index) const                                  \
    { return (nodetype *)wxListBase::Item(index); }                 \
    \
    T *operator[](size_t index) const                                   \
    {                                                                   \
      nodetype *node = Item(index);                                   \
      return node ? (T*)(node->GetData()) : (T*)NULL;                 \
    }                                                                   \
    \
    nodetype *Append(Tbase *object)                                     \
    { return (nodetype *)wxListBase::Append(object); }              \
    nodetype *Insert(Tbase *object)                                     \
    { return (nodetype *)Insert((nodetype*)NULL, object); }         \
    nodetype *Insert(size_t pos, Tbase *object)                         \
    { return (nodetype *)wxListBase::Insert(pos, object); }         \
    nodetype *Insert(nodetype *prev, Tbase *object)                     \
    { return (nodetype *)wxListBase::Insert(prev, object); }        \
    \
    nodetype *Append(long key, void *object)                            \
    { return (nodetype *)wxListBase::Append(key, object); }         \
    nodetype *Append(const wxChar *key, void *object)                   \
    { return (nodetype *)wxListBase::Append(key, object); }         \
    \
    nodetype *DetachNode(nodetype *node)                                \
    { return (nodetype *)wxListBase::DetachNode(node); }            \
    bool DeleteNode(nodetype *node)                                     \
    { return wxListBase::DeleteNode(node); }                        \
    bool DeleteObject(Tbase *object)                                    \
    { return wxListBase::DeleteObject(object); }                    \
    void Erase(nodetype *it)                                            \
    { DeleteNode(it); }                                             \
    \
    nodetype *Find(const Tbase *object) const                           \
    { return (nodetype *)wxListBase::Find(object); }                \
    \
    virtual nodetype *Find(const wxListKey& key) const                  \
    { return (nodetype *)wxListBase::Find(key); }                   \
    \
    int IndexOf(Tbase *object) const                                    \
    { return wxListBase::IndexOf(object); }                         \
    \
    void Sort(wxSortCompareFunction func)                               \
    { wxListBase::Sort(func); }                                     \
    void Sort(wxSortFuncFor_##name func)                                \
    { Sort((wxSortCompareFunction)func); }                          \
    \
  protected:                                                              \
    virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,  \
                                   void *data,                                  \
                                   const wxListKey& key = wxDefaultListKey)     \
    {                                                               \
      return new nodetype(this,                                   \
                          (nodetype *)prev, (nodetype *)next,     \
                          (T *)data, key);                        \
    }                                                               \
  public:                                                                 \
    typedef size_t size_type;                                           \
    typedef int difference_type;                                        \
    typedef T* value_type;                                              \
    typedef Tbase* base_value_type;                                     \
    typedef value_type& reference;                                      \
    typedef const value_type& const_reference;                          \
    typedef base_value_type& base_reference;                            \
    typedef const base_value_type& const_base_reference;                \
    \
    class iterator                                                   \
    {                                                                   \
      typedef name list;                                              \
    public:                                                             \
      typedef nodetype Node;                                          \
      typedef iterator itor;                                          \
      typedef T* value_type;                                          \
      typedef value_type* ptr_type;                                   \
      typedef value_type& reference;                                  \
      \
      Node* m_node;                                                   \
      Node* m_init;                                                   \
    public:                                                             \
      typedef reference reference_type;                               \
      typedef ptr_type pointer_type;                                  \
      \
      iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
      iterator() : m_node(NULL), m_init(NULL) { }                     \
      reference_type operator*() const                                \
      { return *(pointer_type)m_node->GetDataPtr(); }             \
      ptrop                                                           \
      itor& operator++() { m_node = m_node->GetNext(); return *this; }\
      const itor operator++(int)                                      \
      { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
      itor& operator--()                                              \
      {                                                               \
        m_node = m_node ? m_node->GetPrevious() : m_init;           \
        return *this;                                               \
      }                                                               \
      const itor operator--(int)                                      \
      {                                                               \
        itor tmp = *this;                                           \
        m_node = m_node ? m_node->GetPrevious() : m_init;           \
        return tmp;                                                 \
      }                                                               \
      bool operator!=(const itor& it) const                           \
      { return it.m_node != m_node; }                             \
      bool operator==(const itor& it) const                           \
      { return it.m_node == m_node; }                             \
    };                                                                  \
    class const_iterator                                             \
    {                                                                   \
      typedef name list;                                              \
    public:                                                             \
      typedef nodetype Node;                                          \
      typedef T* value_type;                                          \
      typedef const value_type& const_reference;                      \
      typedef const_iterator itor;                                    \
      typedef value_type* ptr_type;                                   \
      \
      Node* m_node;                                                   \
      Node* m_init;                                                   \
    public:                                                             \
      typedef const_reference reference_type;                         \
      typedef const ptr_type pointer_type;                            \
      \
      const_iterator(Node* node, Node* init)                          \
        : m_node(node), m_init(init) { }                            \
      const_iterator() : m_node(NULL), m_init(NULL) { }               \
      const_iterator(const iterator& it)                              \
        : m_node(it.m_node), m_init(it.m_init) { }                  \
      reference_type operator*() const                                \
      { return *(pointer_type)m_node->GetDataPtr(); }             \
      ptrop                                                           \
      itor& operator++() { m_node = m_node->GetNext(); return *this; }\
      const itor operator++(int)                                      \
      { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
      itor& operator--()                                              \
      {                                                               \
        m_node = m_node ? m_node->GetPrevious() : m_init;           \
        return *this;                                               \
      }                                                               \
      const itor operator--(int)                                      \
      {                                                               \
        itor tmp = *this;                                           \
        m_node = m_node ? m_node->GetPrevious() : m_init;           \
        return tmp;                                                 \
      }                                                               \
      bool operator!=(const itor& it) const                           \
      { return it.m_node != m_node; }                             \
      bool operator==(const itor& it) const                           \
      { return it.m_node == m_node; }                             \
    };                                                                  \
    class reverse_iterator                                           \
    {                                                                   \
      typedef name list;                                              \
    public:                                                             \
      typedef nodetype Node;                                          \
      typedef T* value_type;                                          \
      typedef reverse_iterator itor;                                  \
      typedef value_type* ptr_type;                                   \
      typedef value_type& reference;                                  \
      \
      Node* m_node;                                                   \
      Node* m_init;                                                   \
    public:                                                             \
      typedef reference reference_type;                               \
      typedef ptr_type pointer_type;                                  \
      \
      reverse_iterator(Node* node, Node* init)                        \
        : m_node(node), m_init(init) { }                            \
      reverse_iterator() : m_node(NULL), m_init(NULL) { }             \
      reference_type operator*() const                                \
      { return *(pointer_type)m_node->GetDataPtr(); }             \
      ptrop                                                           \
      itor& operator++()                                              \
      { m_node = m_node->GetPrevious(); return *this; }           \
      const itor operator++(int)                                      \
      { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
      itor& operator--()                                              \
      { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
      const itor operator--(int)                                      \
      {                                                               \
        itor tmp = *this;                                           \
        m_node = m_node ? m_node->GetNext() : m_init;               \
        return tmp;                                                 \
      }                                                               \
      bool operator!=(const itor& it) const                           \
      { return it.m_node != m_node; }                             \
      bool operator==(const itor& it) const                           \
      { return it.m_node == m_node; }                             \
    };                                                                  \
    class const_reverse_iterator                                     \
    {                                                                   \
      typedef name list;                                              \
    public:                                                             \
      typedef nodetype Node;                                          \
      typedef T* value_type;                                          \
      typedef const_reverse_iterator itor;                            \
      typedef value_type* ptr_type;                                   \
      typedef const value_type& const_reference;                      \
      \
      Node* m_node;                                                   \
      Node* m_init;                                                   \
    public:                                                             \
      typedef const_reference reference_type;                         \
      typedef const ptr_type pointer_type;                            \
      \
      const_reverse_iterator(Node* node, Node* init)                  \
        : m_node(node), m_init(init) { }                            \
      const_reverse_iterator() : m_node(NULL), m_init(NULL) { }       \
      const_reverse_iterator(const reverse_iterator& it)              \
        : m_node(it.m_node), m_init(it.m_init) { }                  \
      reference_type operator*() const                                \
      { return *(pointer_type)m_node->GetDataPtr(); }             \
      ptrop                                                           \
      itor& operator++()                                              \
      { m_node = m_node->GetPrevious(); return *this; }           \
      const itor operator++(int)                                      \
      { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
      itor& operator--()                                              \
      { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
      const itor operator--(int)                                      \
      {                                                               \
        itor tmp = *this;                                           \
        m_node = m_node ? m_node->GetNext() : m_init;               \
        return tmp;                                                 \
      }                                                               \
      bool operator!=(const itor& it) const                           \
      { return it.m_node != m_node; }                             \
      bool operator==(const itor& it) const                           \
      { return it.m_node == m_node; }                             \
    };                                                                  \
    \
    wxEXPLICIT name(size_type n, const_reference v = value_type())      \
    { assign(n, v); }                                               \
    name(const const_iterator& first, const const_iterator& last)       \
    { assign(first, last); }                                        \
    iterator begin() { return iterator(GetFirst(), GetLast()); }        \
    const_iterator begin() const                                        \
    { return const_iterator(GetFirst(), GetLast()); }               \
    iterator end() { return iterator(NULL, GetLast()); }                \
    const_iterator end() const { return const_iterator(NULL, GetLast()); }\
    reverse_iterator rbegin()                                           \
    { return reverse_iterator(GetLast(), GetFirst()); }             \
    const_reverse_iterator rbegin() const                               \
    { return const_reverse_iterator(GetLast(), GetFirst()); }       \
    reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
    const_reverse_iterator rend() const                                 \
    { return const_reverse_iterator(NULL, GetFirst()); }            \
    void resize(size_type n, value_type v = value_type())               \
    {                                                                   \
      while (n < size())                                              \
        pop_back();                                                 \
      while (n > size())                                              \
        push_back(v);                                                \
    }                                                                   \
    size_type size() const { return GetCount(); }                       \
    size_type max_size() const { return INT_MAX; }                      \
    bool empty() const { return IsEmpty(); }                            \
    reference front() { return *begin(); }                              \
    const_reference front() const { return *begin(); }                  \
    reference back() { iterator tmp = end(); return *--tmp; }           \
    const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
    void push_front(const_reference v = value_type())                   \
    { Insert(GetFirst(), (const_base_reference)v); }                \
    void pop_front() { DeleteNode(GetFirst()); }                        \
    void push_back(const_reference v = value_type())                    \
    { Append((const_base_reference)v); }                            \
    void pop_back() { DeleteNode(GetLast()); }                          \
    void assign(const_iterator first, const const_iterator& last)       \
    {                                                                   \
      clear();                                                        \
      for(; first != last; ++first)                                   \
        Append((const_base_reference)*first);                       \
    }                                                                   \
    void assign(size_type n, const_reference v = value_type())          \
    {                                                                   \
      clear();                                                        \
      for(size_type i = 0; i < n; ++i)                                \
        Append((const_base_reference)v);                            \
    }                                                                   \
    iterator insert(const iterator& it, const_reference v = value_type())\
    {                                                                   \
      if ( it == end() )                                              \
        Append((const_base_reference)v);                            \
      else                                                            \
        Insert(it.m_node, (const_base_reference)v);                 \
      iterator itprev(it);                                            \
      return itprev--;                                                \
    }                                                                   \
    void insert(const iterator& it, size_type n, const_reference v = value_type())\
    {                                                                   \
      for(size_type i = 0; i < n; ++i)                                \
        insert(it, v);                                              \
    }                                                                   \
    void insert(const iterator& it, const_iterator first, const const_iterator& last)\
    {                                                                   \
      for(; first != last; ++first)                                   \
        insert(it, *first);                                         \
    }                                                                   \
    iterator erase(const iterator& it)                                  \
    {                                                                   \
      iterator next = iterator(it.m_node->GetNext(), GetLast());      \
      DeleteNode(it.m_node); return next;                             \
    }                                                                   \
    iterator erase(const iterator& first, const iterator& last)         \
    {                                                                   \
      iterator next = last;                                           \
      if ( next != end() )                                            \
        ++next;                                                     \
      DeleteNodes(first.m_node, last.m_node);                         \
      return next;                                                    \
    }                                                                   \
    void clear() { Clear(); }                                           \
    void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
    { insert(it, first, last); l.erase(first, last); }              \
    void splice(const iterator& it, name& l)                            \
    { splice(it, l, l.begin(), l.end() ); }                         \
    void splice(const iterator& it, name& l, const iterator& first)     \
    {                                                                   \
      if ( it != first )                                              \
      {                                                               \
        insert(it, *first);                                         \
        l.erase(first);                                             \
      }                                                               \
    }                                                                   \
    void remove(const_reference v)                                      \
    { DeleteObject((const_base_reference)v); }                      \
    void reverse()                                                      \
    { Reverse(); }                                                  \
  }

#define WX_LIST_PTROP                                                       \
  pointer_type operator->() const                                 \
  { return (pointer_type)m_node->GetDataPtr(); }
#define WX_LIST_PTROP_NONE

#define WX_DECLARE_LIST_3(T, Tbase, name, nodetype)               \
  WX_DECLARE_LIST_4(T, Tbase, name, nodetype, WX_LIST_PTROP_NONE)
#define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp)        \
  WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)

#define WX_DECLARE_LIST_2(elementtype, listname, nodename)        \
  WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename)
#define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp)        \
  WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)

#define WX_DECLARE_LIST(elementtype, listname)                              \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node)
#define WX_DECLARE_LIST_PTR(elementtype, listname)                              \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node)

#define WX_DECLARE_LIST_WITH_DECL(elementtype, listname) \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node)

#define WX_DECLARE_EXPORTED_LIST(elementtype, listname)                     \
  WX_DECLARE_LIST_WITH_DECL(elementtype, listname)

#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname)                     \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node)

#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname)       \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node)
#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo)       \
  typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
  WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node)

#define WX_DEFINE_LIST(name)    "don't forget to include listimpl.cpp!"

#define WX_DEFINE_EXPORTED_LIST(name)      WX_DEFINE_LIST(name)
#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)

#if defined(wxLIST_COMPATIBILITY)

inline wxNode *wxNodeBase::Next() const { return ( wxNode * )GetNext(); }
inline wxNode *wxNodeBase::Previous() const { return ( wxNode * )GetPrevious(); }
inline wxObject *wxNodeBase::Data() const { return ( wxObject * )GetData(); }
inline int wxListBase::Number() const { return ( int )GetCount(); }
inline wxNode *wxListBase::First() const { return ( wxNode * )GetFirst(); }
inline wxNode *wxListBase::Last() const { return ( wxNode * )GetLast(); }
inline wxNode *wxListBase::Nth( size_t n ) const { return ( wxNode * )Item( n ); }
inline wxListBase::operator wxList&() const { return *( wxList* )this; }

WX_DECLARE_LIST_2( wxObject, wxObjectList, wxObjectListNode);

class wxList : public wxObjectList {
  public:
    #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
    wxList() { };
    wxDEPRECATED( wxList( int key_type ) );
    #elif !wxUSE_STL
    wxList( int key_type = wxKEY_NONE );
    #endif
    ~wxList() { }

    wxList& operator=( const wxList& list ) { ( void ) wxListBase::operator=( list ); return *this; }

    // compatibility methods
    void Sort( wxSortCompareFunction compfunc ) { wxListBase::Sort( compfunc ); }
    wxNode *Member( wxObject *object ) const { return ( wxNode * )Find( object ); }

  private:
    DECLARE_DYNAMIC_CLASS( wxList )
};


WX_DECLARE_LIST_2( wxChar, wxStringListBase, wxStringListNode );

class wxStringList : public wxStringListBase {
  public:
    // ctors and such
    // default
    #ifdef wxWARN_COMPAT_LIST_USE
    wxStringList();
    wxDEPRECATED( wxStringList( const wxChar *first ... ) );
    #else
    wxStringList();
    wxStringList( const wxChar *first ... );
    #endif

    // copying the string list: the strings are copied, too (extremely
    // inefficient!)
    wxStringList( const wxStringList& other ) : wxStringListBase() { DeleteContents( true ); DoCopy( other ); }
    wxStringList& operator=( const wxStringList& other ) { Clear(); DoCopy( other ); return *this; }

    // operations
    // makes a copy of the string
    wxNode *Add( const wxChar *s );

    // Append to beginning of list
    wxNode *Prepend( const wxChar *s );

    bool Delete( const wxChar *s );

    wxChar **ListToArray( bool new_copies = false ) const;
    bool Member( const wxChar *s ) const;

    // alphabetic sort
    void Sort();

  private:
    void DoCopy( const wxStringList& ); // common part of copy ctor and operator=

    DECLARE_DYNAMIC_CLASS( wxStringList )
};


#endif

#define WX_CLEAR_LIST(type, list)                                            \
  {                                                                        \
    type::iterator it, en;                                               \
    for( it = (list).begin(), en = (list).end(); it != en; ++it )        \
      delete *it;                                                      \
    (list).clear();                                                      \
  }

#endif // _WX_LISTH__
